﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YJKGeometryFuncs;
using YJKRevitDimensionText.DimCreator;

namespace YJKRevitDimensionText.OneKeyPlanDim.OutWallThreeDim
{
	public class GridOperationUtil
	{
		public static XYZ GetYDirMinGridUpEndPoint(Autodesk.Revit.DB.Document doc, ElementId viewId, XYZ vecDir, double dMaxValue, double dTrans)
		{
			List<Grid> vectorParallelGrid = GridOperationUtil.GetVectorParallelGrid(doc, viewId, vecDir);
			XYZ result = null;
			double num = double.MaxValue;
			foreach (Grid grid in vectorParallelGrid)
			{
				XYZ endPoint = grid.Curve.GetEndPoint(0);
				XYZ endPoint2 = grid.Curve.GetEndPoint(1);
				XYZ xyz = endPoint;
				XYZ xyz2 = (endPoint2 - endPoint).Normalize();
				if (endPoint.Y < endPoint2.Y)
				{
					xyz = endPoint2;
					xyz2 = -xyz2;
				}
				if (xyz.Y >= dMaxValue && xyz.Y < num)
				{
					result = xyz + xyz2.Multiply(dTrans);
					num = xyz.Y;
				}
			}
			return result;
		}

		public static XYZ GetXDirMinGridRightEndPoint(Autodesk.Revit.DB.Document doc, ElementId viewId, XYZ vecDir, double dMaxValue, double dTrans)
		{
			List<Grid> vectorParallelGrid = GridOperationUtil.GetVectorParallelGrid(doc, viewId, vecDir);
			XYZ result = null;
			double num = double.MaxValue;
			foreach (Grid grid in vectorParallelGrid)
			{
				XYZ endPoint = grid.Curve.GetEndPoint(0);
				XYZ endPoint2 = grid.Curve.GetEndPoint(1);
				XYZ xyz = endPoint;
				XYZ xyz2 = (endPoint2 - endPoint).Normalize();
				if (endPoint.X < endPoint2.X)
				{
					xyz = endPoint2;
					xyz2 = -xyz2;
				}
				if (xyz.X >= dMaxValue && xyz.X < num)
				{
					result = xyz + xyz2.Multiply(dTrans);
					num = xyz.X;
				}
			}
			return result;
		}

		public static List<Grid> GetVectorParallelGrid(Autodesk.Revit.DB.Document doc, ElementId viewId, XYZ vecDir)
		{
			List<Grid> list = new List<Grid>();
			foreach (Grid grid in GridOperationUtil.GetAllLineGrid(doc, viewId))
			{
				Line line = grid.Curve as Line;
				if (null != line && Geometry.IsParallel(line.Direction.Normalize(), vecDir.Normalize()))
				{
					list.Add(grid);
				}
			}
			return list;
		}

		public static List<Grid> GetAllLineGrid(Autodesk.Revit.DB.Document doc, ElementId viewId)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc, viewId);
			filteredElementCollector.OfCategory(BuiltInCategory.OST_Grids).WhereElementIsNotElementType();
			List<Grid> list = new List<Grid>();
			foreach (Element element in filteredElementCollector)
			{
				Grid grid = element as Grid;
				if (grid != null && grid.Curve is Line)
				{
					list.Add(grid);
				}
			}
			return list;
		}

		public static XYZ GetLineGridCenter(Grid grid)
		{
			Line line = grid.Curve as Line;
			if (null != line)
			{
				return Geometry.CalculatMidPoint(line);
			}
			return null;
		}

		public static XYZ GetLineGridSameDirPoint(Grid grid, XYZ vecDir)
		{
			Curve curve = grid.Curve;
			XYZ endPoint = curve.GetEndPoint(0);
			XYZ endPoint2 = curve.GetEndPoint(1);
			if ((endPoint2 - endPoint).Normalize().IsAlmostEqualTo(vecDir.Normalize()))
			{
				return endPoint2;
			}
			return endPoint;
		}

		public static void GetGridDimRef(UIApplication uiApp, Grid grid, out Reference gridRef)
		{
			gridRef = null;
			Options options = uiApp.Application.Create.NewGeometryOptions();
			options.ComputeReferences = true;
			options.IncludeNonVisibleObjects = false;
			options.View = uiApp.ActiveUIDocument.Document.ActiveView;
			GridType gridType = uiApp.ActiveUIDocument.Document.GetElement(grid.GetTypeId()) as GridType;
			int num = RevitElementExtension.GetParameter(gridType, BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).AsInteger();
			if (num != 0)
			{
				RevitElementExtension.GetParameter(gridType, BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).Set(0);
				uiApp.ActiveUIDocument.Document.Regenerate();
			}
			foreach (GeometryObject geometryObject in RevitVersionFuncs.GetGeometryObjectArray(grid.get_Geometry(options)))
			{
				if (geometryObject is Curve)
				{
					Curve curve = geometryObject as Curve;
					if (curve.Reference != null)
					{
						gridRef = curve.Reference;
					}
				}
			}
			if (num != 0)
			{
				RevitElementExtension.GetParameter(gridType, BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).Set(num);
			}
		}

		public static XYZ GetGridDirection(Grid lindGrid)
		{
			Line line = lindGrid.Curve as Line;
			if (null != line)
			{
				return line.Direction.Normalize();
			}
			return XYZ.Zero;
		}

		public static Wall GetWallByGrid(Grid grid, List<Wall> lstWall)
		{
			foreach (Wall wall in lstWall)
			{
				XYZ gridDirection = GridOperationUtil.GetGridDirection(grid);
				XYZ wallLocVector = WallOperattionUtil.GetWallLocVector(wall);
				if (Geometry.IsParallel(gridDirection, wallLocVector))
				{
					XYZ wallLocationCenter = WallOperattionUtil.GetWallLocationCenter(wall);
					XYZ xyz = wallLocationCenter + wall.Orientation.Normalize().Multiply(wall.Width / 2.0);
					XYZ xyz2 = wallLocationCenter - wall.Orientation.Normalize().Multiply(wall.Width / 2.0);
					Curve zeroHeightCurve = OutWallThreeDimManager.GetZeroHeightCurve(Line.CreateBound(xyz, xyz2));
					Curve zeroHeightCurve2 = OutWallThreeDimManager.GetZeroHeightCurve(grid.Curve);
					IntersectionResultArray intersectionResultArray = null;
					zeroHeightCurve2.Intersect(zeroHeightCurve, out intersectionResultArray);
					if (intersectionResultArray != null && intersectionResultArray.Size == 1)
					{
						return wall;
					}
				}
			}
			return null;
		}

		public static Grid GetNearestPointGrid(UIApplication uiApp, XYZ pt, XYZ vecTrans)
		{
			Grid result = null;
			List<Grid> allLineGrid = GridOperationUtil.GetAllLineGrid(uiApp.ActiveUIDocument.Document, uiApp.ActiveUIDocument.ActiveView.Id);
			double num = 6.5616797900262469;
			XYZ xyz = DimPublicFunc.To2d(pt);
			XYZ xyz2 = xyz + vecTrans.Normalize().Multiply(num);
			Line line = Line.CreateBound(xyz, xyz2);
			line.MakeUnbound();
			double num2 = double.MaxValue;
			foreach (Grid grid in allLineGrid)
			{
				if (!grid.IsHidden(uiApp.ActiveUIDocument.ActiveView))
				{
					Line line2 = grid.Curve as Line;
					if (!(null == line2) && Geometry.IsVertical(vecTrans.Normalize(), line2.Direction.Normalize()))
					{
						Curve zeroHeightCurve = OutWallThreeDimManager.GetZeroHeightCurve(grid.Curve);
						IntersectionResultArray intersectionResultArray = null;
						line.Intersect(zeroHeightCurve, out intersectionResultArray);
						if (intersectionResultArray != null && intersectionResultArray.Size == 1)
						{
							double num3 = intersectionResultArray.get_Item(0).XYZPoint.DistanceTo(xyz);
							if (num3 < num2)
							{
								result = grid;
								num2 = num3;
							}
						}
					}
				}
			}
			return result;
		}
	}
}
